﻿using System;
using System.Linq;
using EPiServer.Core;
using EPiServer.Filters;

namespace EPiBoost.Core.Filters.PageFilters
{
    public class FilterCategory : IPageFilter
    {
        public enum FilterExpressionMode { Or, And }

        /// <summary>
        /// A collection of the selected categories to search on
        /// </summary>
        public CategoryList Categories{ get; set; }

        /// <summary>
        /// 
        /// </summary>
        public FilterExpressionMode FilterExpression { get; set; }

        public FilterCategory()
        {
        }

        public FilterCategory(CategoryList categoryList)
        {
            this.Categories = categoryList;
        }

        public void FilterAllCategories(PageDataCollection pages)
        {
            for (int i = pages.Count - 1; i >= 0; i--)
            {
                bool isMatch = false;
                var pageCategories = pages[i].Category;

                if (pageCategories != null && pageCategories.Count < Categories.Count)
                {
                    int matchCount = (from category in pageCategories
                                      from currentCategory in this.Categories
                                      where category == currentCategory
                                      select category).Count();
                    isMatch = matchCount == Categories.Count;
                }

                if (!isMatch)
                {
                    pages.RemoveAt(i);
                }
            }
        }

        public void Filter(PageDataCollection pages)
        {
            if (FilterExpression == FilterExpressionMode.And)
            {
                for (int i = pages.Count - 1; i >= 0; i--)
                {
                    bool isMatch = false;
                    var pageCategories = pages[i].Category;

                    if (pageCategories != null && pageCategories.Count > 0 && pageCategories.Count >= this.Categories.Count)
                    {
                        int matchCount = 0;
                        foreach (var category in pageCategories)
                        {
                            foreach (var currentCategory in this.Categories)
                            {
                                if (category == currentCategory)
                                {
                                    matchCount++;
                                }
                            }
                        }
                        isMatch = matchCount > 0 && matchCount == Categories.Count;
                    }

                    if (!isMatch)
                    {
                        pages.RemoveAt(i);
                    }
                }
            }
            else
            {
                for (int i = pages.Count - 1; i >= 0; i--)
                {
                    bool isMatch = false;
                    var categoryList = pages[i].Category;

                    if (categoryList != null)
                    {
                        foreach (var category in categoryList)
                        {
                            foreach (var currentCategory in this.Categories)
                            {
                                if (category == currentCategory)
                                {
                                    isMatch = true;
                                }
                            }
                        }
                    }

                    if (!isMatch)
                    {
                        pages.RemoveAt(i);
                    }
                }
            }

        }

        public void Filter(object sender, FilterEventArgs e)
        {
            Filter(e.Pages);
        }

        public bool ShouldFilter(PageData page)
        {
            throw new NotImplementedException();
        }
    }
}
